﻿using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
using ZedGraph;

namespace Bioinformatics.Controls
{
    /// <summary>
    /// Class provides graphical representation of performance data and functionality to permanently store data.
    /// </summary>
    public class PerformanceGraph : ZedGraphControl
    {
        private Dictionary<string, PointPairList> _performanceDataRepository;

        /// <summary>
        /// Initializes a default instance of the PerformanceGraph class.
        /// </summary>
        public PerformanceGraph()
        {
            //set default titles
            GraphPane.Title.Text = "Performance Graph";
            GraphPane.Title.FontSpec.Size = 8.0f;
            GraphPane.XAxis.Title.Text = "Swarm Size";
            GraphPane.XAxis.Title.FontSpec.Size = 8.0f;
            GraphPane.YAxis.Title.Text = "Time (ms)";
            GraphPane.YAxis.Title.FontSpec.Size = 8.0f;
        }

        /// <summary>
        /// Adds performance data to both the repository and the graph.
        /// </summary>
        /// <param name="title">Unique identifier for the data - will be used as key.</param>
        /// <param name="performanceData">The data to be added.</param>
        public void AddPerformanceData(string title, PointPairList performanceData)
        {
            //add the data to the repository
            _performanceDataRepository.Add(title, performanceData);
            //update the graph
            updateGraph();
        }

        /// <summary>
        /// Retrieves the performance data repository from a binary file.
        /// </summary>
        /// <param name="path">Source path of the file to read from.</param>
        public void ImportData(string path)
        {
            //open the source path
            FileStream fstream = File.OpenRead(path);
            //create binary formatter
            var binaryFormatter = new BinaryFormatter();
            //deserialize the object from the binary file
            _performanceDataRepository = (Dictionary<string, PointPairList>) binaryFormatter.Deserialize(fstream);
            //close the file stream
            fstream.Close();
            //update the graph
            updateGraph();
        }

        /// <summary>
        /// Saves the performance data repository to a binary file.
        /// </summary>
        /// <param name="path">Destination path of the file to write to</param>
        public void SaveData(string path)
        {
            //open the source path
            FileStream fstream = File.OpenWrite(path);
            //create the binary formatter
            var binaryFormatter = new BinaryFormatter();
            //serialize the object to the binary file
            binaryFormatter.Serialize(fstream, _performanceDataRepository);
            //close the file stream
            fstream.Close();
        }

        private void updateGraph()
        {
            //clear all curves currently drawn on the chart
            GraphPane.CurveList.Clear();
            //add each point pair list currently held in the repository
            foreach (string performanceDataTitle in _performanceDataRepository.Keys)
                GraphPane.AddCurve(performanceDataTitle, _performanceDataRepository[performanceDataTitle], Color.Black);
            //update the axis scaling
            AxisChange();
            //force the chart to redraw itself
            Invalidate();
        }
    }
}